package cc.md888.app.application.totp;


import cc.md888.app.exception.BizRuntimeException;
import cc.md888.app.model.common.TotpCodeVO;
import cc.md888.result.ResultCode;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.warrenstrange.googleauth.GoogleAuthenticator;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Component
public class TotpService {

    private static final int TIME_STEP_SIZE_IN_SECONDS = 30;

    private final GoogleAuthenticator gAuth = new GoogleAuthenticator();


    private Cache<String, Long> expireInCache = CacheBuilder.newBuilder()
            .expireAfterWrite(1, TimeUnit.MINUTES)
            .build();


    /**
     * 获取totp密码
     * @param secretKey
     */
    public TotpCodeVO getTotpCode(String secretKey){
        if (StringUtils.isEmpty(secretKey)) {
            throw BizRuntimeException.from(ResultCode.ERROR, "2fa安全密钥不能为空");
        }
        //移除空格
        long now = System.currentTimeMillis();
        secretKey = secretKey.replace(" ", "");
        int totpCode =  gAuth.getTotpPassword(secretKey) ;
        String code = String.format("%06d", totpCode);
        TotpCodeVO totpCodeVO = new TotpCodeVO();
        totpCodeVO.setCode(code);

        String cacheKey = secretKey + "_" + code;
        Long genTime = expireInCache.getIfPresent(cacheKey);
        if(genTime == null){
            totpCodeVO.setExpireIn(TIME_STEP_SIZE_IN_SECONDS);
            expireInCache.put(cacheKey, now);
        }else{
            int spent = Math.toIntExact(TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis() - genTime));
            int remaining = Math.min(TIME_STEP_SIZE_IN_SECONDS, TIME_STEP_SIZE_IN_SECONDS - spent);
            totpCodeVO.setExpireIn(remaining);
        }
        return totpCodeVO;
    }



}
